home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 112 / EnigmaAmiga112CD.iso / dalla rivista / awnpipe / awnp / awnp-docs / tutorials / tutorial4.c < prev    next >
C/C++ Source or Header  |  2000-01-04  |  14KB  |  522 lines

  1. #include <dos/dos.h>
  2. #include <clib/dos_protos.h>       /* General dos functions...    */
  3. #include <stdio.h>                 /* Std functions [printf()...] */
  4. #include <stdlib.h>                /* Std functions [exit()...]   */
  5. #include <string.h>
  6.  
  7.  
  8. /*We pass 'GP' alot but it allows for multiple GUI's in a single aplication*/
  9.  int main( int argc, char *argv[]);
  10.  int getline(struct GUIpipe * GP);
  11.  int topipe(struct GUIpipe * GP, UBYTE * data,...);
  12.  int gperror(struct GUIpipe * GP,int error);
  13.  int buildgui(struct GUIpipe * GP);
  14.  int getevent(struct GUIpipe * GP);
  15.  int gadgets(struct GUIpipe * GP);
  16.  int menu(struct GUIpipe * GP);
  17.  UBYTE * eventstr(struct GUIpipe * GP, int num);
  18.  VOID setdefaults(VOID);
  19.  int updategui(struct GUIpipe * GP);
  20.  int saveform(VOID);
  21.  int loadform(struct GUIpipe * GP);
  22.  int showtx(int delay,UBYTE * text,...);
  23.  int iconify(struct GUIpipe * GP);
  24.  int appdrop(struct GUIpipe * GP);
  25.  int readfile(UBYTE * fn);
  26.  int setenv(struct GUIpipe * GP);
  27.  int setenvarc(struct GUIpipe * GP);
  28.  int unsetenvarc(struct GUIpipe * GP);
  29.  int readenv(VOID);
  30.  
  31.  
  32. /* This structure is used to magage a GUI*/
  33. /*events information and results from topipe() are kept seperate */
  34.  struct GUIpipe
  35.   {
  36.    BPTR file;
  37.    UBYTE * nextline;
  38.    int count,error;
  39.    int val1,val2,val3,val4,val5,val6;
  40.    UBYTE buf[500],str3[200];
  41.    UBYTE str1[20],result1[50],result2[50];
  42.   };
  43.  
  44. /* the structure to mantain the GUI */
  45.  struct GUIpipe myGP;
  46.  
  47. /* Storage for gadget ID's */
  48.  int namegad,agegad,sexgad,knogad,basgad,aregad,cgad,asmgad,resgad,
  49.  dongad,cangad;
  50.  int savegad,loadgad,getfilegad;
  51.  
  52. /*NEW FOR TUTORIAL4 remember if the gui is iconified or not*/
  53. short iconified;
  54.  
  55. /* the forms information */
  56.  int age,sex,knowledge,basic,arexx,c,asm;
  57.  UBYTE name[104];
  58.  
  59. /*for env snapshots*/
  60. UBYTE * envname="env:GUITutorial4", * envarcname="envarc:GUITutorial4";
  61. int wintop,winleft,winhigh,winwide;
  62.  
  63.  int main( int argc, char *argv[] )
  64.   {
  65.    struct GUIpipe * GP = &myGP;
  66.    int stop=0;
  67.    setdefaults();
  68. /*try to build the GUI and use it*/
  69.    if(!buildgui(GP))
  70.     {
  71. /* we disable the savegadget after the gui first opens*/
  72.      topipe(GP,"id %ld dis 1 ref\n",savegad);
  73.  
  74. /* we loop until we are told to stop or an error happens*/
  75.      while(!GP->error&&!stop)
  76.       {
  77. /*send continue to tell the pipe no more modify commands are comming and we
  78. want an event*/
  79.        topipe(GP,"con\n");
  80.  
  81. /* read an event.*/
  82.        getevent(GP);
  83.  
  84. /*since we have received an event the pipe is now ready to get modify
  85. commands again*/
  86. /* the first two letter of each event type are different. For this GUI one
  87. letter would be enough . SASC requires you turn the Multiple Character
  88. Constants option on (MCConstants) .*/
  89.        switch(GP->str1[1]+(GP->str1[0]<<8))
  90.         {
  91.          case('ap'):
  92.          stop=appdrop(GP);
  93.          break;
  94.          case('ga'):
  95.          stop=gadgets(GP);
  96.          break;
  97.          case('ic'):
  98.          iconify(GP);
  99.          break;
  100.          case('me'):
  101.          stop=menu(GP);
  102.          break;
  103.          case('cl'):
  104.          showtx(200,"User Closed Window or used CTRl\\");
  105.          stop=1;
  106.          break;
  107.         }
  108.       }
  109.     }
  110.  
  111. /*close the pipe connection*/
  112.    if(GP->file)Close(GP->file);
  113.    exit( 0 );
  114.   }
  115.  
  116.  
  117. /*open the file on AWNPipe:, send the window and gadget definitions,
  118.  open the GUI window, return 0 for sucess or an error number*/
  119.  buildgui(struct GUIpipe * GP)
  120.   {
  121. /* Open pipe 'tut3' with GUI creation option '/xc' */
  122.    if(!( GP->file=Open("awnpipe:tut4/xc",MODE_OLDFILE))) return(1);
  123.  
  124.    /* The first line of every GUI is the window definition. The window is titled
  125. "Tutorial 3" and its elements will be laid out verticaly (v). It has a
  126. closegadget (cg) , depthgadget (dg) , and dragbar (db). It will have spaces
  127. inbetween its gadgets (si). It will open on the topleft (tl) of the screen
  128. becoming active (a) when opened. The GUI can be modified (m). It is an 'app
  129. window' that icons can be dropped on (app).*/
  130.  
  131. /* if we find a vaid env file we use its settings.*/
  132. if (readenv()) topipe(GP," \"Tutorial 4\" app v cg dg db sg fh si ig ii \"tutorial4\" a m top %ld left %ld width %ld height %ld\n",wintop,winleft,winhigh,winwide);
  133. else    topipe(GP," \"Tutorial 4\" app v cg dg db sg fh si ig ii \"tutorial4\" a tl m\n");
  134.  
  135.    /* define the gadgets*/
  136.    /* Labels are used to tell the user what information to enter in each gadget.
  137. These labels are unatached (ua) when they are defined so don't go directly
  138. into the GUI. Instead they are attached to the following gadget by the
  139. childlabel (chl) keyword. */
  140.  
  141.    topipe(GP," layout b 0 v\n");
  142.    topipe(GP," label gt \"Name: \" ua\n");
  143.    namegad=topipe(GP,"string lj chl\n");
  144.    topipe(GP," label gt \"Age: \" ua\n");
  145.    agegad=topipe(GP,"integer chl minn 10 maxn 99 arrows defn 30  weiw 0\n");
  146.    topipe(GP," label gt \"Sex: \" ua\n");
  147.    sexgad=topipe(GP,"radiobutton rl \"Male|Female\" chl\n");
  148.    topipe(GP," label gt \"Knowledge: \" ua\n");
  149.    knogad=topipe(GP,"chooser pu cl \"Novice|Average|Good|Expert\" chl\n");
  150.    topipe(GP," label gt \"Language(s): \" ua\n");
  151.    topipe(GP," layout b 0 chl\n");
  152.    basgad=topipe(GP,"checkbox gt \"Basic \" chl\n");
  153.    aregad=topipe(GP,"checkbox gt \"Arexx \" chl\n");
  154.    cgad=topipe(GP,"checkbox gt \"C \" chl\n");
  155.    asmgad=topipe(GP,"checkbox gt \"ASM \" chl\n");
  156.    topipe(GP," le\n");
  157.    topipe(GP," le\n");
  158.    topipe(GP," layout si so\n");
  159.    savegad= topipe(GP,"button gt \"Save\" \n");
  160.    loadgad= topipe(GP,"button gt \"Load\" \n");
  161.    resgad= topipe(GP,"button gt \"Reset Form\" \n");
  162.    dongad= topipe(GP,"button gt \"Done\" c\n");
  163.    cangad= topipe(GP,"button gt \"Cancel\" c\n");
  164.    topipe(GP," le\n");
  165.    topipe(GP," menu gt \"Project|Window|$@SSnapshot|$@UUnSnapshot|-|About\"\n");
  166.    topipe(GP," menu gt \"Data|@AShow all data|Show part|$@PPersonal|$@SSkill\"\n");
  167.  
  168. /* this gadget is unattached so does not show in the GUI. It is used by the
  169. loadform() routine. */
  170.    getfilegad= topipe(GP,"getfile gt \"Select Information File\" fn \"t:\" ua pat \"#?.tut3\" \n");
  171.  
  172.    /*open the GUI window if all is ok*/
  173.    if(!GP->error) topipe(GP,"open\n");
  174.    return(GP->error);
  175.   }
  176.  
  177.  int getline(struct GUIpipe * GP)
  178.   {
  179.    int in;
  180.    if(GP->nextline)
  181.     {
  182.      GP->count-=(GP->nextline-GP->buf);
  183. memmove(GP->buf,GP->nextline,GP->count);
  184.      GP->nextline=0;
  185.     }
  186. /*read pipe until we have an linefeed*/
  187. while (!(GP->nextline=memchr(GP->buf,'\n',GP->count))) {
  188.  
  189.        if(!(in=Read(GP->file,&(GP->buf[GP->count]),499-GP->count)))
  190.         {
  191. /*error on EOF or lines over 499 chars.*/
  192.          gperror(GP,1);
  193.          return(1);
  194.         }
  195.        GP->count+=in;
  196.       }
  197.  
  198. /* mark the end of line*/
  199.    *GP->nextline++=0;
  200.    return(0);
  201.   }
  202.  
  203.  
  204. /*write formated data to the pipe (works like printf),
  205.  read the responce from the pipe and parse it,
  206.  return the value of the second parameter is the responce is ok,
  207.  return 0 if we have a problem*/
  208.  __stdargs int topipe(struct GUIpipe * GP, UBYTE * data,...)
  209.   {
  210.    VFPrintf(GP->file,data,(APTR)(4+(int)(&data)) );
  211.    if(getline(GP)) return(0);
  212.    sscanf(GP->buf,"%50s %50s",GP->result1,GP->result2);
  213.    if(!strcmp(GP->result1,"ok"))return(atoi(GP->result2));
  214.    gperror(GP,2);
  215.    return(0);
  216.   }
  217.  
  218.  
  219. /* GP->error could simply be set rather then calling this routine
  220. but its politer to alert the user somehow */
  221.  int gperror(struct GUIpipe * GP,int error)
  222.   {
  223.    GP->error=error;
  224.    showtx(0,"ERROR %ld*n",GP->error);
  225.    return(0);
  226.   }
  227.  
  228. /* read a line from the pipe and parse it for event information*/
  229.  int getevent(struct GUIpipe * GP)
  230.   {
  231. UBYTE * s3;
  232.    if(!getline(GP))
  233.     {
  234.      sscanf(GP->buf,"%20s %d %d %d %d %d",
  235.             GP->str1,&GP->val2,&GP->val3,
  236.             &GP->val4,&GP->val5,&GP->val6);
  237.      sscanf(GP->buf,"%d",&GP->val1);
  238. if (s3=eventstr(GP,3)){
  239. if (strlen(s3)<200)strcpy(GP->str3,s3);
  240. else memmove(GP->str3,s3,199);
  241.     }
  242. }
  243.    return(GP->error);
  244.   }
  245.  
  246. /* find the start of the 'num' parameter.
  247. ONLY CALL THIS FUCNTION IMEDIATLY AFTER RECEIVING A LINE.
  248. Then store a copy of the string, NOT THE POINTER */
  249.  UBYTE * eventstr(struct GUIpipe * GP,int num)
  250.   {
  251.    UBYTE *a;
  252.    a=GP->buf;
  253.    while((num--)>1)
  254.     {
  255.      a=strchr(a,' ');
  256.      if(!a)return(0);
  257.      a++;
  258.     }
  259.    return(a);
  260.   }
  261.  
  262. /* store the information from the event, or perform an action
  263.  we return 1 if the gui should be closed, or 0 to keep going*/
  264.  int gadgets(struct GUIpipe * GP)
  265.   {
  266.    int a;
  267.    a=GP->val2;
  268.    if(a==agegad)     age=GP->val3;
  269.    if(a==sexgad)     sex=GP->val3;
  270.    if(a==knogad)     knowledge=GP->val3;
  271.    if(a==basgad)     basic=GP->val3;
  272.    if(a==aregad)     arexx=GP->val3;
  273.    if(a==cgad)       c=GP->val3;
  274.    if(a==asmgad)     asm=GP->val3;
  275.    if(a==namegad)
  276.     {
  277.      strcpy(name,GP->str3);
  278. /* disable the save gadget if we do not have a name, enable it if we do*/
  279.      return(topipe(GP,"id %ld dis %ld ref\n",savegad, (strlen(name))?0:1 ));
  280.     }
  281.    if(a==loadgad) return(loadform(GP));
  282.    if(a==savegad) return(saveform());
  283.    if(a==resgad)
  284.     {
  285.      setdefaults();
  286.      return(updategui(GP));
  287.     }
  288.    if(a==cangad)
  289.     {
  290.      showtx(200,"User Canceled\n");
  291.      return(1);
  292.     }
  293.    if(a==dongad)
  294.     {
  295.      showtx(0,"name: %s*n age: %ld*n sex: %ld*nknowledge: %ld*n basic: %ld arexx: %ld c: %ld asm: %ld ",
  296.  name,age,sex,knowledge,basic,arexx,c,asm);
  297.      return(1);
  298.     }
  299.    return(0);
  300.   }
  301.  
  302. /*react to the menu event. menu#=val2, menuitem#=val3,subitem#=val4*/
  303.  int menu(struct GUIpipe * GP)
  304. {
  305.    if(GP->val2==0)
  306.   {
  307. if (GP->val3==2)showtx(500," Tutorial 4 for AWNP *n  by William Parker");
  308. if (GP->val3==0){
  309. if (GP->val4==0) setenvarc(GP);
  310. if (GP->val4==1) unsetenvarc(GP);
  311. }
  312. }
  313.    if(GP->val2==1)
  314.     {
  315.      if(GP->val3==0)
  316.       {
  317.      showtx(200,"name: %s*n age: %ld*n sex: %ld*nknowledge: %ld*n basic: %ld arexx: %ld c: %ld asm: %ld ",
  318.  name,age,sex,knowledge,basic,arexx,c,asm);
  319.       }
  320.  
  321.      if(GP->val3==1)
  322.       {
  323.        if(GP->val4==0)
  324.         {
  325.          showtx(200,"name %s age %ld sex %ld", name,age,sex);
  326.         }
  327.        if(GP->val4==1)
  328.         {
  329.          showtx(200,"knowledge %ld basic %ld arexx %ld c %ld asm %ld",
  330.                 knowledge,basic,arexx,c,asm);
  331.         }
  332.       }
  333.     }
  334.    return(0);
  335.   }
  336.  
  337. /*initialize our information to default state*/
  338.  VOID setdefaults()
  339.   {
  340.    *name=0;
  341.    age=30;
  342.    sex=0 ;
  343.    knowledge=0;
  344.    basic=0;
  345.    c=0;
  346.    asm=0;
  347.    arexx=0;
  348.   }
  349.  
  350. /* send modify commands to update our GUI to the current information*/
  351.  int updategui(struct GUIpipe * GP)
  352.   {
  353.    topipe(GP,"id %ld defn %ld ref\n",agegad,age);
  354.    topipe(GP,"id %ld s %ld ref\n",sexgad,sex);
  355.    topipe(GP,"id %ld s %ld ref \n",knogad,knowledge);
  356.    topipe(GP,"id %ld s %ld ref\n",basgad,basic);
  357.    topipe(GP,"id %ld s %ld ref\n",aregad,arexx);
  358.    topipe(GP,"id %ld s %ld ref \n",cgad,c );
  359.    topipe(GP,"id %ld s %ld ref\n",asmgad,asm);
  360.    topipe(GP,"id %ld gt \"%ls\" ref\n",namegad,name);
  361.    topipe(GP,"id %ld dis %ld ref\n",savegad,(strlen(name))?0:1);
  362.    return(GP->error);
  363.   }
  364.  
  365. /*write our information to a file. Build the file name from the 'name'
  366. information*/
  367.  int saveform()
  368.   {
  369.    UBYTE buf[200];
  370.    BPTR fh;
  371.    if (strlen(name)&&strlen(name)<192){
  372.    strcat(strcat(strcpy(buf,"t:"),name),".tut3");
  373.    if(fh=Open(buf,MODE_READWRITE))
  374.     {
  375.      FPrintf(fh,"%ld %ld %ld %ld %ld %ld %ld %ls",
  376.              age ,sex ,knowledge,basic,arexx,c,asm,name);
  377.      Close(fh);
  378.      return(0);
  379.     }
  380. }
  381.    return(1);
  382.   }
  383.  
  384. /* open our unattached getfile gadget to select a file.
  385. read the file and store the information.*/
  386.  int loadform(struct GUIpipe * GP)
  387.   {
  388.    UBYTE buf[100],*b,*c;
  389.    b=buf;
  390.    c=buf;
  391. /* we do not use topipe() since we want to parse the return from this modify
  392. command as an event. This is a special case */
  393.    FPrintf(GP->file,"id %ld fn \"t:\" s 1\n",getfilegad);
  394.    if (getevent(GP)) return(1);
  395. /*val 1 is 0 if the user canceled the file requester, non zero if a file was
  396. selected*/
  397.    if(GP->val1)
  398.     {
  399. /*The file name is returned in quotes. Copy the real file name from between
  400. the quotes. Damn the "Ram Disk:"*/
  401.      if(!(b=eventstr(GP,2))) return(1);
  402.      b++;
  403.      while(*b!='"')*c++=*b++;
  404.      *c++=0;
  405. /*open and read the file, parse the info*/
  406.      if(readfile(buf))  updategui(GP);
  407.     }
  408.    return(0);
  409.   }
  410.  
  411. int readfile(UBYTE * fn)
  412. {
  413.    BPTR fh;
  414. UBYTE buf[117];
  415. int a;
  416.      if(fh=Open(fn,MODE_OLDFILE))
  417.       {
  418.        a=Read(fh,buf,116);
  419.        buf[a]=0;
  420.        Close(fh);
  421.        sscanf(buf,"%ld %ld %ld %ld %ld %ld %ld",
  422.               &age ,&sex ,&knowledge,&basic,&arexx,&c,&asm);
  423.        strcpy(name,&buf[15]);
  424. return(1);
  425.       }
  426. return(0);
  427. }
  428.  
  429. int showtx(int delay,UBYTE * text,...)
  430. {
  431. BPTR win;
  432. if(win= Open("awnpipe:tut4txt/xc",MODE_READWRITE))
  433. {
  434. FPrintf(win,"db dg \"Tutorial 4\" q cg cm m a so si\nlabel lj gt \"");
  435. VFPrintf(win,text,(APTR)(4+(int)(&text)) );
  436. FPrintf(win,"\"\nopen\n");
  437. if (delay)FPrintf(win,"tick %ld\n",delay);
  438. else FPrintf(win,"m\n");
  439. Close(win);
  440. }
  441. return(0);
  442. }
  443.  
  444. int appdrop(struct GUIpipe * GP)
  445. {
  446. UBYTE * fn;
  447. if(fn=eventstr(GP,2)){
  448.  
  449. /* Make sure we have a quoted file name (should always be true..but)
  450. and skip/remove the quotes.*/
  451. if(fn[strlen(fn)-1]='\"'){
  452. fn[strlen(fn)-1]=0;
  453. fn++;
  454. }
  455.  if(readfile(fn)) {
  456. topipe(GP,"id 0 s 64\n");
  457. iconified=0;
  458.  updategui(GP);
  459. }
  460. }
  461. return(0);
  462. }
  463.  
  464. int iconify(struct GUIpipe * GP)
  465. {
  466. iconified=GP->val2;
  467. if (GP->val2==1) topipe(GP,"id 0 s 32\n");
  468. else  topipe(GP,"id 0 s 64\n");
  469. return(0);
  470. }
  471.  
  472. /* we do not use topipe() since we dont want error checking on the special
  473. return from this modify command. This is a special case */
  474. int  setenv(struct GUIpipe * GP)
  475. {
  476. BPTR fh;
  477.    FPrintf(GP->file,"id 0 read\n");
  478.    if (!getline(GP)) {
  479.   if( fh=Open(envname,MODE_NEWFILE)){
  480. Write(fh,GP->buf,strlen(GP->buf));
  481.   Close(fh);
  482. return(1);
  483. }
  484. }
  485. return(0);
  486. }
  487.  
  488. int  setenvarc(struct GUIpipe * GP)
  489. {
  490. BPTR fh;
  491. if(setenv(GP)){
  492. /* gp->buf already holds the info we want to save*/
  493.  if( fh=Open(envarcname,MODE_NEWFILE)){
  494. Write(fh,GP->buf,strlen(GP->buf));
  495.   Close(fh);
  496. return(1);
  497. }
  498. }
  499. return(0);
  500. }
  501.  
  502. int  unsetenvarc(struct GUIpipe * GP)
  503. {
  504. DeleteFile(envarcname);
  505. DeleteFile(envname);
  506. return(1);
  507. }
  508.  
  509. int  readenv()
  510. {
  511. BPTR fh;
  512. UBYTE buf[100];
  513. int in;
  514.  if( fh=Open(envname,MODE_OLDFILE)){
  515. in=Read(fh,buf,99);
  516. buf[in]=0;
  517. Close(fh);
  518. return(sscanf(buf,"%ld %ld %ld %ld",&winleft,&wintop,&winhigh,&winwide));
  519. }
  520. return(0);
  521. }
  522.